﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.SharePoint;
using Alerts_Administration_2010.interfaces.models;
using Alerts_Administration_2010.interfaces;
using Alerts_Administration_2010.interfaces.views;

namespace Alerts_Administration_2010.classes.controller
{
    public class AlertDetailsController
    {
        #region private fields
        private IAlertWrapper _alertWrapper;
        private IAlertDetailsView _view;
        
        private Dictionary<SPEventType, string> _changeTypes = new Dictionary<SPEventType, string>();
        private Dictionary<SPAlertFrequency, string> _frequencies = new Dictionary<SPAlertFrequency, string>();
        #endregion

        #region public properties
        public IAlertDetailsView AttachedView
        {
            get
            {
                return _view;
            }
            set
            {
                _view = value;
                _view.ChangeTypeChanged += new EventHandler<EventArgs>(_view_ChangeTypeChanged);
                _view.Confirmed += new EventHandler<EventArgs>(_view_Confirmed);

                UpdateView();
            }
        }
        #endregion
         
        public AlertDetailsController(IAlertWrapper alertWrapper)
        {
            _alertWrapper = alertWrapper;

            _changeTypes.Add(SPEventType.All, "All changes");
            _changeTypes.Add(SPEventType.Add, "New items are added");
            _changeTypes.Add(SPEventType.Modify, "Existing items are modified");
            _changeTypes.Add(SPEventType.Delete, "Items are deleted");
            _changeTypes.Add(SPEventType.Discussion, "Web discussion updates");

            _frequencies.Add(SPAlertFrequency.Immediate, "Send e-mail immediatetly");
            _frequencies.Add(SPAlertFrequency.Daily, "Send a daily summary");
            _frequencies.Add(SPAlertFrequency.Weekly, "Send a weekly summary");
        }

        #region event handler
        private void _view_ChangeTypeChanged(object sender, EventArgs e)
        {
            switch (GetAlertFrequency(_view.Frequency))
            {
                case Microsoft.SharePoint.SPAlertFrequency.Daily:
                    _view.HourEnabled = true;
                    _view.DayEnabled = false;
                    break;
                case Microsoft.SharePoint.SPAlertFrequency.Immediate:
                    _view.HourEnabled = false;
                    _view.DayEnabled = false;
                    break;
                case Microsoft.SharePoint.SPAlertFrequency.Weekly:
                    _view.HourEnabled = true;
                    _view.DayEnabled = true;
                    break;
                default:
                    break;
            }
        }
        private void _view_Confirmed(object sender, EventArgs e)
        {
            _alertWrapper.Alert.Title = _view.AlertTitle;
            _alertWrapper.Alert.EventType = GetEventType(_view.ChangeType);
            switch (_alertWrapper.Alert.EventType)
            {
                case SPEventType.Add:
                    _alertWrapper.Alert.Properties["eventtypeindex"] = "1";
                    break;
                case SPEventType.All:
                    _alertWrapper.Alert.Properties["eventtypeindex"] = "0";
                    break;
                case SPEventType.Delete:
                    _alertWrapper.Alert.Properties["eventtypeindex"] = "3";
                    break;
                case SPEventType.Discussion:
                    _alertWrapper.Alert.Properties["eventtypeindex"] = "4";
                    break;
                case SPEventType.Modify:
                    _alertWrapper.Alert.Properties["eventtypeindex"] = "2";
                    break;
                default:
                    break;
            }
            foreach (IAlertTemplateFilter filter in _alertWrapper.TemplateFilterList)
            {
                if (filter.FriendlyName == _view.Filter)
                {
                    _alertWrapper.Alert.Filter = filter.QueryNode.OuterXml;
                    _alertWrapper.Alert.Properties["filterindex"] = filter.Index.ToString();
                    break;
                }
            }
            _alertWrapper.Alert.AlertFrequency = GetAlertFrequency(_view.Frequency);
            switch (_alertWrapper.Alert.AlertFrequency)
            {
                case SPAlertFrequency.Daily:
                    {
                        int hour = int.Parse(_view.AlertHour);
                        DateTime potentialAlertTime = new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day, hour, 0, 0);
                        if (DateTime.Now >= potentialAlertTime)
                        {
                            potentialAlertTime = potentialAlertTime.AddDays(1);
                        }
                        _alertWrapper.Alert.AlertTime = potentialAlertTime;
                    }
                    break;
                case SPAlertFrequency.Immediate:
                    break;
                case SPAlertFrequency.Weekly:
                    {
                        int hour = int.Parse(_view.AlertHour);
                        DateTime potentialAlertTime = new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day, hour, 0, 0);
                        while ((DateTime.Now > potentialAlertTime) || (potentialAlertTime.DayOfWeek.ToString() != _view.AlertDay))
                        {
                            potentialAlertTime = potentialAlertTime.AddDays(1);
                        }
                        _alertWrapper.Alert.AlertTime = potentialAlertTime;
                    }
                    break;
                default:
                    break;
            }

            _alertWrapper.Alert.Update(false);
        }
        #endregion

        #region private methods
        private void UpdateView()
        {
            if ((_view != null) && (_alertWrapper != null))
            {
                _view.SetFilters(GetFilterStrings(_alertWrapper));
                _view.SetFrequencies(_frequencies.Values);
                _view.SetChangeTypes(_changeTypes.Values);

                _view.AlertTitle = _alertWrapper.Alert.Title;
                _view.EmailAddress = _alertWrapper.Alert.User.Email;
                _view.ChangeType = _changeTypes[_alertWrapper.Alert.EventType];
                _view.ChangeTypeVisible = _alertWrapper.Alert.AlertType == SPAlertType.List;
                //_view.Filter = _alertWrapper.SelectedTemplateFilter.FriendlyName;
                _view.Filter = _alertWrapper.TemplateFilterList[int.Parse(_alertWrapper.Alert.Properties["filterindex"])].FriendlyName;
                _view.Frequency = _frequencies[_alertWrapper.Alert.AlertFrequency];

                SetFrequencyDropDowns(_alertWrapper.Alert.AlertFrequency);
            }
            _view.Render();
        }
        private IEnumerable<string> GetFilterStrings(IAlertWrapper model)
        {
            foreach (IAlertTemplateFilter filter in model.TemplateFilterList)
            {
                yield return filter.FriendlyName;
            }
        }
        private SPAlertFrequency GetAlertFrequency(string s)
        {
            foreach (KeyValuePair<SPAlertFrequency, string> kvp in _frequencies)
            {
                if (kvp.Value == s) return kvp.Key;
            }
            throw new IndexOutOfRangeException();
        }
        private SPEventType GetEventType(string s)
        {
            foreach (KeyValuePair<SPEventType, string> kvp in _changeTypes)
            {
                if (kvp.Value == s) return kvp.Key;
            }
            throw new IndexOutOfRangeException();
        }
        private void SetFrequencyDropDowns(SPAlertFrequency frequency)
        {
            switch (frequency)
            {
                case Microsoft.SharePoint.SPAlertFrequency.Daily:
                    _view.HourEnabled = true;
                    _view.AlertHour = _alertWrapper.Alert.AlertTime.Hour.ToString();
                    _view.DayEnabled = false;
                    break;
                case Microsoft.SharePoint.SPAlertFrequency.Immediate:
                    _view.HourEnabled = false;
                    _view.DayEnabled = false;
                    break;
                case Microsoft.SharePoint.SPAlertFrequency.Weekly:
                    _view.HourEnabled = true;
                    _view.AlertHour = _alertWrapper.Alert.AlertTime.Hour.ToString();
                    _view.DayEnabled = true;
                    _view.AlertDay = _alertWrapper.Alert.AlertTime.DayOfWeek.ToString();
                    break;
                default:
                    break;
            }
        }
        #endregion
    }
}
